/*
 * URL.cpp
 *
 *  Created on: 2010-6-19
 *      Author: SW
 */

#include "URL.h"
#include <iostream>

namespace HA {
URL::URL(const string& spec) :
	protocol(""), hostname(""), path(""), parameters(""), query(""), fragment(
			""), port(-1) {
	parseURL(spec);
}

void URL::parseURL(const string& spec) {
	string::size_type index = -1;
	string::size_type commaIndex = -1;
	string::size_type slashIndex = -1;
	string::size_type hostnameCommaIndex = -1;
	string::size_type hostnameSlashIndex = -1;
	string::size_type portIndex = -1;
	string::size_type pathIndex = -1;
	string::size_type parametersIndex = -1;
	string::size_type queryIndex = -1;
	string::size_type fragmentIndex = -1;

	//Get the position of : and //
	commaIndex = spec.find_first_of(":");
	slashIndex = spec.find_first_of("//");

	//If :// not exists
	if (commaIndex == string::npos) {
		cout << "The URL you input is not correct!" << endl;
		return;
	} else if (slashIndex == string::npos) {
		cout << "The URL you input is not correct!" << endl;
		return;
	} else if ((slashIndex - commaIndex) != 1) {
		cout << "The URL you input is not correct!" << endl;
		return;
	}

	//Get the position of ://
	index = spec.find_first_of("://");

	//Get protocol
	if (index != string::npos) {
		// Check if hostname existed
		if (spec.length() == index + 3) {
			cout << "The URL you input is not correct!" << endl;
			return;
		}
		//Get protocol from the beginning to the font one character of ://
		protocol = spec.substr(0, index);
	}

	//Get hostname
	//Get the position of the character following ://
	index = index + 3;
	if (index != string::npos) {
		//Get the position of : after hostname
		hostnameCommaIndex = spec.find_first_of(":", index);
		//If : before port exists
		if (hostnameCommaIndex != string::npos) {
			//Get hostname from the character following :// to the character before :
			//Note: the : is the one after hostname
			hostname = spec.substr(index, hostnameCommaIndex - index);
		} else {
			//If : before port exists
			hostnameSlashIndex = spec.find_first_of("/", index);
			//Get hostname from the character following :// to the character before /
			//Note: the / is the one before path
			if (hostnameSlashIndex != string::npos)
				hostname = spec.substr(index, hostnameSlashIndex - index);
			else {
				hostname = spec.substr(index);
				return;//no path part
			}

		}

	}

	//Get port
	if (hostnameCommaIndex != string::npos) {
		//Get the position of / before path
		portIndex = spec.find_first_of("/", hostnameCommaIndex);
		if (portIndex != string::npos) {
			string mPort = spec.substr(hostnameCommaIndex + 1, portIndex
					- hostnameCommaIndex - 1);
			port = atoi(mPort.c_str());
		}
	}

	//Get path
	//if port exists
	if (portIndex != string::npos) {
		//Get the position of / after path
		pathIndex = spec.find_first_of("/", portIndex + 1);
		if (pathIndex != string::npos) {
			path = spec.substr(portIndex + 1, pathIndex - portIndex - 1);
		}
	}
	//if port not exists
	else if (hostnameSlashIndex != string::npos) {
		pathIndex = spec.find_first_of("/", hostnameSlashIndex + 1);
		if (pathIndex != string::npos) {
			path = spec.substr(hostnameSlashIndex + 1, pathIndex
					- hostnameSlashIndex - 1);
		}
	} else
		path = "";

	parametersIndex = spec.find_first_of(";", pathIndex + 1);
	queryIndex = spec.find_first_of("?", parametersIndex + 1);
	fragmentIndex = spec.find_first_of("#", fragmentIndex + 1);

	//Get parameter
	if (parametersIndex != string::npos) {
		//If query exists
		if (queryIndex != string::npos) {
			parameters = spec.substr(parametersIndex + 1, queryIndex
					- parametersIndex - 1);
		}
		//If query not exists, but fragments exists
		else if (fragmentIndex != string::npos) {
			parameters = spec.substr(parametersIndex + 1, fragmentIndex
					- parametersIndex - 1);
		}
	} else {
		parameters = "";
	}

	//Get query
	if (queryIndex != string::npos) {
		if (fragmentIndex != string::npos) {
			query = spec.substr(queryIndex + 1, fragmentIndex - queryIndex - 1);
		}
	}

	//Get fragment
	fragmentIndex = spec.find_last_of("#");
	if (fragmentIndex != string::npos) {
		fragment = spec.substr(fragmentIndex + 1);
	}
}

}

//URL::~URL() {
//      // TODO Auto-generated destructor stub
//}

//}


